#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Fei Gao <feig@princeton.edu>
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause

from litex.build.generic_platform import *
from litex.build.xilinx import XilinxUSPPlatform, VivadoProgrammer

# IOs ----------------------------------------------------------------------------------------------

_io = [
    # Clk / Rst
    ("clk300", 0,
        Subsignal("p", Pins("G31"), IOStandard("DIFF_SSTL12")),
        Subsignal("n", Pins("F31"), IOStandard("DIFF_SSTL12")),
    ),
    ("clk250", 0,
        Subsignal("p", Pins("E12"), IOStandard("DIFF_SSTL12")),
        Subsignal("n", Pins("D12"), IOStandard("DIFF_SSTL12")),
    ),
    ("clk250", 1,
        Subsignal("p", Pins("AW26"), IOStandard("DIFF_SSTL12")),
        Subsignal("n", Pins("AW27"), IOStandard("DIFF_SSTL12")),
    ),
    ("clk125", 0,
        Subsignal("p", Pins("AY24"), IOStandard("LVDS")),
        Subsignal("n", Pins("AY23"), IOStandard("LVDS")),
    ),
    ("clk156", 0,
        Subsignal("p", Pins("H32"), IOStandard("DIFF_SSTL12")),
        Subsignal("n", Pins("G32"), IOStandard("DIFF_SSTL12")),
    ),
    ("cpu_reset", 0, Pins("L19"), IOStandard("LVCMOS12")),

    # Leds
    ("user_led", 0, Pins("AT32"), IOStandard("LVCMOS12")),
    ("user_led", 1, Pins("AV34"), IOStandard("LVCMOS12")),
    ("user_led", 2, Pins("AY30"), IOStandard("LVCMOS12")),
    ("user_led", 3, Pins("BB32"), IOStandard("LVCMOS12")),
    ("user_led", 4, Pins("BF32"), IOStandard("LVCMOS12")),
    ("user_led", 5, Pins("AU37"), IOStandard("LVCMOS12")),
    ("user_led", 6, Pins("AV36"), IOStandard("LVCMOS12")),
    ("user_led", 7, Pins("BA37"), IOStandard("LVCMOS12")),

    # Switches
    ("user_dip_btn", 0, Pins("B17"), IOStandard("LVCMOS12")),
    ("user_dip_btn", 1, Pins("G16"), IOStandard("LVCMOS12")),
    ("user_dip_btn", 2, Pins("J16"), IOStandard("LVCMOS12")),
    ("user_dip_btn", 3, Pins("D21"), IOStandard("LVCMOS12")),

    # Buttons
    ("user_btn_c", 0, Pins("BD23"), IOStandard("LVCMOS18")),
    ("user_btn_n", 0, Pins("BB24"), IOStandard("LVCMOS18")),
    ("user_btn_e", 0, Pins("BE23"), IOStandard("LVCMOS18")),
    ("user_btn_s", 0, Pins("BE22"), IOStandard("LVCMOS18")),
    ("user_btn_w", 0, Pins("BF22"), IOStandard("LVCMOS18")),

    # I2C
    ("i2c", 0,
        Subsignal("scl", Pins("AM24"), IOStandard("LVCMOS18")),
        Subsignal("sda", Pins("AL24"), IOStandard("LVCMOS18")),
    ),
    ("i2c_mux_reset_n", 0, Pins("AL25"), IOStandard("LVCMOS18")),

    # Serial
    ("serial", 0,
        Subsignal("rx",  Pins("AW25"), IOStandard("LVCMOS18")),
        Subsignal("rts", Pins("BB22"), IOStandard("LVCMOS18")),
        Subsignal("tx",  Pins("BB21"), IOStandard("LVCMOS18")),
        Subsignal("cts", Pins("AY25"), IOStandard("LVCMOS18")),
    ),

    # DDR4 memory channel C1. Only use the first 64 data bits
    ("ddram", 0,
        Subsignal("a", Pins(
            "D14 B15 B16 C14 C15 A13 A14 A15",
            "A16 B12 C12 B13 C13 D15"),
            IOStandard("SSTL12_DCI")),
        Subsignal("ba",        Pins("G15 G13"), IOStandard("SSTL12_DCI")),
        Subsignal("bg",        Pins("H13"), IOStandard("SSTL12_DCI")),
        Subsignal("ras_n",     Pins("F15"), IOStandard("SSTL12_DCI")), # A16
        Subsignal("cas_n",     Pins("H15"), IOStandard("SSTL12_DCI")), # A15
        Subsignal("we_n",      Pins("H14"), IOStandard("SSTL12_DCI")), # A14
        Subsignal("cs_n",      Pins("F13"), IOStandard("SSTL12_DCI")),
        Subsignal("act_n",     Pins("E13"), IOStandard("SSTL12_DCI")),
        #Subsignal("ten",       Pins("A20"), IOStandard("SSTL12_DCI")),
        #Subsignal("alert_n",   Pins("R17"), IOStandard("SSTL12_DCI")),
        #Subsignal("par",       Pins("G10"), IOStandard("SSTL12_DCI")),
        Subsignal("dm",        Pins(
            "G11 R18 K17 G18 B18 P20 L23 G22"),
            IOStandard("POD12_DCI")),
        Subsignal("dq",        Pins(
            "F11 E11 F10  F9 H12 G12  E9  D9",
            "R19 P19 M18 M17 N19 N18 N17 M16",
            "L16 K16 L18 K18 J17 H17 H19 H18",
            "F19 F18 E19 E18 G20 F20 E17 D16",
            "D17 C17 C19 C18 D20 D19 C20 B20",
            "N23 M23 R21 P21 R22 P22 T23 R23",
            "K24 J24 M21 L21 K21 J21 K22 J22",
            "H23 H22 E23 E22 F21 E21 F24 F23"),
            IOStandard("POD12_DCI"),
            Misc("PRE_EMPHASIS=RDRV_240"),
            Misc("EQUALIZATION=EQ_LEVEL2")),
        Subsignal("dqs_p",   Pins("D11 P17 K19 F16 A19 N22 M20 H24"),
		    IOStandard("DIFF_POD12"),
            Misc("PRE_EMPHASIS=RDRV_240"),
            Misc("EQUALIZATION=EQ_LEVEL2")),
        Subsignal("dqs_n",   Pins("D10 P16 J19 E16 A18 M22 L20 G23"),
		    IOStandard("DIFF_POD12"),
            Misc("PRE_EMPHASIS=RDRV_240"),
            Misc("EQUALIZATION=EQ_LEVEL2")),
        Subsignal("clk_p",   Pins("F14"), IOStandard("DIFF_SSTL12_DCI")),
        Subsignal("clk_n",   Pins("E14"), IOStandard("DIFF_SSTL12_DCI")),
        Subsignal("cke",     Pins("A10"), IOStandard("SSTL12_DCI")),
        Subsignal("odt",     Pins("C8"), IOStandard("SSTL12_DCI")),
        Subsignal("reset_n", Pins("N20"), IOStandard("LVCMOS12")),
        Misc("SLEW=FAST"),
    ),

    # DDR4 memory channel C2.
    ("ddram", 1,
        Subsignal("a", Pins(
            "AM27 AL27 AP26 AP25 AN28 AM28 AP28 AP27",
            "AN26 AM26 AR28 AR27 AV25 AT25"),
            IOStandard("SSTL12_DCI")),
        Subsignal("ba",      Pins("AR25 AU28"), IOStandard("SSTL12_DCI")),
        Subsignal("bg",      Pins("AU27"), IOStandard("SSTL12_DCI")),
        Subsignal("ras_n",   Pins("AV26"), IOStandard("SSTL12_DCI")), # A16
        Subsignal("cas_n",   Pins("AU26"), IOStandard("SSTL12_DCI")), # A15
        Subsignal("we_n",    Pins("AV28"), IOStandard("SSTL12_DCI")), # A14
        Subsignal("cs_n",    Pins("AY29"), IOStandard("SSTL12_DCI")),
        Subsignal("act_n",   Pins("AN25"), IOStandard("SSTL12_DCI")),
        #Subsignal("ten",     Pins("AY35"), IOStandard("SSTL12_DCI")),
        #Subsignal("alert_n", Pins("AR29"), IOStandard("SSTL12_DCI")),
        #Subsignal("par",     Pins("BF29"), IOStandard("SSTL12_DCI")),
        Subsignal("dm",      Pins(
            "BE32 BB31 AV33 AR32 BC34 BE40 AY37 AV35 BE29 BA29"),
            IOStandard("POD12_DCI")),
        Subsignal("dq",      Pins(
            "BD30 BE30 BD32 BE33 BC33 BD33 BC31 BD31",
            "BA32 BB33 BA30 BA31 AW31 AW32 AY32 AY33",
            "AV30 AW30 AU33 AU34 AT31 AU32 AU31 AV31",
            "AR33 AT34 AT29 AT30 AP30 AR30 AN30 AN31",
            "BE34 BF34 BC35 BC36 BD36 BE37 BF36 BF37",
            "BD37 BE38 BC39 BD40 BB38 BB39 BC38 BD38",
            "BB36 BB37 BA39 BA40 AW40 AY40 AY38 AY39",
            "AW35 AW36 AU40 AV40 AU38 AU39 AV38 AV39",
            "BF26 BF27 BD28 BE28 BD27 BE27 BD25 BD26",
            "BC25 BC26 BB28 BC28 AY27 AY28 BA27 BB27"),
            IOStandard("POD12_DCI"),
            Misc("PRE_EMPHASIS=RDRV_240"),
            Misc("EQUALIZATION=EQ_LEVEL2")),
        Subsignal("dqs_p",   Pins(
            "BF30 AY34 AU29 AP31 BE35 BE39 BA35 AW37 BE25 BA26"),
            IOStandard("DIFF_POD12"),
            Misc("PRE_EMPHASIS=RDRV_240"),
            Misc("EQUALIZATION=EQ_LEVEL2")),
        Subsignal("dqs_n",   Pins(
            "BF31 BA34 AV29 AP32 BF35 BF39 BA36 AW38 BF25 BB26"),
            IOStandard("DIFF_POD12"),
            Misc("PRE_EMPHASIS=RDRV_240"),
            Misc("EQUALIZATION=EQ_LEVEL2")),
        Subsignal("clk_p",   Pins("AT26"), IOStandard("DIFF_SSTL12_DCI")),
        Subsignal("clk_n",   Pins("AT27"), IOStandard("DIFF_SSTL12_DCI")),
        Subsignal("cke",     Pins("AW28"), IOStandard("SSTL12_DCI")),
        Subsignal("odt",     Pins("BB29"), IOStandard("SSTL12_DCI")),
        Subsignal("reset_n", Pins("BD35"), IOStandard("LVCMOS12")),
        Misc("SLEW=FAST"),
    ),
]

# Connectors ---------------------------------------------------------------------------------------

_connectors = [
    ("PMOD0", "AY14 AY15 AW15 AV15 AV16 AU16 AT15 AT16"),
    ("PMOD1", "N28 M30 N30 P30 P29 L31 M31 R29"),
    ("FMC_HPC1", {
        "CLK0_M2C_N"  : "BC8",
        "CLK0_M2C_P"  : "BC9",
        "CLK1_M2C_N"  : "AV13",
        "CLK1_M2C_P"  : "AV14",

        "LA00_CC_N"   : "BA9",
        "LA00_CC_P"   : "AY9",
        "LA01_CC_N"   : "BF9",
        "LA01_CC_P"   : "BF10",
        "LA02_N"      : "BD11",
        "LA02_P"      : "BC11",
        "LA03_N"      : "BE12",
        "LA03_P"      : "BD12",
        "LA04_N"      : "BF11",
        "LA04_P"      : "BF12",
        "LA05_N"      : "BF14",
        "LA05_P"      : "BE14",
        "LA06_N"      : "BE13",
        "LA06_P"      : "BD13",
        "LA07_N"      : "BD15",
        "LA07_P"      : "BC15",
        "LA08_N"      : "BF15",
        "LA08_P"      : "BE15",
        "LA09_N"      : "BB14",
        "LA09_P"      : "BA14",
        "LA10_N"      : "BB12",
        "LA10_P"      : "BB13",
        "LA11_N"      : "BA15",
        "LA11_P"      : "BA16",
        "LA12_N"      : "BC13",
        "LA12_P"      : "BC14",
        "LA13_N"      : "AY7",
        "LA13_P"      : "AY8",
        "LA14_N"      : "AW7",
        "LA14_P"      : "AW8",
        "LA15_N"      : "BC16",
        "LA15_P"      : "BB16",
        "LA16_N"      : "AV8",
        "LA16_P"      : "AV9",
        "LA17_CC_N"   : "AT14",
        "LA17_CC_P"   : "AR14",
        "LA18_CC_N"   : "AR12",
        "LA18_CC_P"   : "AP12",
        "LA19_N"      : "AY12",
        "LA19_P"      : "AW12",
        "LA20_N"      : "AY10",
        "LA20_P"      : "AW11",
        "LA21_N"      : "AV11",
        "LA21_P"      : "AU11",
        "LA22_N"      : "AY13",
        "LA22_P"      : "AW13",
        "LA23_N"      : "AP16",
        "LA23_P"      : "AN16",
        "LA24_N"      : "AR13",
        "LA24_P"      : "AP13",
        "LA25_N"      : "AU12",
        "LA25_P"      : "AT12",
        "LA26_N"      : "AL15",
        "LA26_P"      : "AK15",
        "LA27_N"      : "AM14",
        "LA27_P"      : "AL14",
        "LA28_N"      : "AW10",
        "LA28_P"      : "AV10",
        "LA29_N"      : "AP15",
        "LA29_P"      : "AN15",
        "LA30_N"      : "AL12",
        "LA30_P"      : "AK12",
        "LA31_N"      : "AM12",
        "LA31_P"      : "AM13",
        "LA32_N"      : "AJ12",
        "LA32_P"      : "AJ13",
        "LA33_N"      : "AK13",
        "LA33_P"      : "AK14",

        "PRSNT_M2C_B" : "BB7",
    }),
    ("FMCP_HSPC", {
        "CLK0_M2C_N"    : "AM32",
        "CLK0_M2C_P"    : "AL32",
        "CLK1_M2C_N"    : "P36",
        "CLK1_M2C_P"    : "P35",

        "LA00_CC_N"     : "AL36",
        "LA00_CC_P"     : "AL35",
        "LA01_CC_N"     : "AL31",
        "LA01_CC_P"     : "AL30",
        "LA02_N"        : "AK32",
        "LA02_P"        : "AJ32",
        "LA03_N"        : "AT40",
        "LA03_P"        : "AT39",
        "LA04_N"        : "AT37",
        "LA04_P"        : "AR37",
        "LA05_N"        : "AR38",
        "LA05_P"        : "AP38",
        "LA06_N"        : "AT36",
        "LA06_P"        : "AT35",
        "LA07_N"        : "AP37",
        "LA07_P"        : "AP36",
        "LA08_N"        : "AK30",
        "LA08_P"        : "AK29",
        "LA09_N"        : "AK33",
        "LA09_P"        : "AJ33",
        "LA10_N"        : "AR35",
        "LA10_P"        : "AP35",
        "LA11_N"        : "AJ31",
        "LA11_P"        : "AJ30",
        "LA12_N"        : "AH34",
        "LA12_P"        : "AH33",
        "LA13_N"        : "AJ36",
        "LA13_P"        : "AJ35",
        "LA14_N"        : "AH31",
        "LA14_P"        : "AG31",
        "LA15_N"        : "AG33",
        "LA15_P"        : "AG32",
        "LA16_N"        : "AH35",
        "LA16_P"        : "AG34",
        "LA17_CC_N"     : "P34",
        "LA17_CC_P"     : "R34",
        "LA18_CC_N"     : "P31",
        "LA18_CC_P"     : "R31",
        "LA19_N"        : "M33",
        "LA19_P"        : "N33",
        "LA20_N"        : "M32",
        "LA20_P"        : "N32",
        "LA21_N"        : "L35",
        "LA21_P"        : "M35",
        "LA22_N"        : "N35",
        "LA22_P"        : "N34",
        "LA23_N"        : "W32",
        "LA23_P"        : "Y32",
        "LA24_N"        : "T35",
        "LA24_P"        : "T34",
        "LA25_N"        : "W34",
        "LA25_P"        : "Y34",
        "LA26_N"        : "U33",
        "LA26_P"        : "V32",
        "LA27_N"        : "V34",
        "LA27_P"        : "V33",
        "LA28_N"        : "L36",
        "LA28_P"        : "M36",
        "LA29_N"        : "T36",
        "LA29_P"        : "U35",
        "LA30_N"        : "M38",
        "LA30_P"        : "N38",
        "LA31_N"        : "N37",
        "LA31_P"        : "P37",
        "LA32_N"        : "K33",
        "LA32_P"        : "L33",
        "LA33_N"        : "K34",
        "LA33_P"        : "L34",

        "HA00_CC_N"     : "N13",
        "HA00_CC_P"     : "N14",
        "HA01_CC_N"     : "U15",
        "HA01_CC_P"     : "V15",
        "HA02_N"        : "Y12",
        "HA02_P"        : "AA12",
        "HA03_N"        : "V12",
        "HA03_P"        : "W12",
        "HA04_N"        : "Y13",
        "HA04_P"        : "AA13",
        "HA05_N"        : "P14",
        "HA05_P"        : "R14",
        "HA06_N"        : "T13",
        "HA06_P"        : "U13",
        "HA07_N"        : "Y14",
        "HA07_P"        : "AA14",
        "HA08_N"        : "T11",
        "HA08_P"        : "U11",
        "HA09_N"        : "V14",
        "HA09_P"        : "W14",
        "HA10_N"        : "U16",
        "HA10_P"        : "V16",
        "HA11_N"        : "P12",
        "HA11_P"        : "R12",
        "HA12_N"        : "T15",
        "HA12_P"        : "T16",
        "HA13_N"        : "U12",
        "HA13_P"        : "V13",
        "HA14_N"        : "L11",
        "HA14_P"        : "M11",
        "HA15_N"        : "M12",
        "HA15_P"        : "M13",
        "HA16_N"        : "R13",
        "HA16_P"        : "T14",
        "HA17_CC_N"     : "P11",
        "HA17_CC_P"     : "R11",
        "HA18_N"        : "N15",
        "HA18_P"        : "P15",
        "HA19_N"        : "L13",
        "HA19_P"        : "L14",
        "HA20_N"        : "L15",
        "HA20_P"        : "M15",
        "HA21_N"        : "K13",
        "HA21_P"        : "K14",
        "HA22_N"        : "J12",
        "HA22_P"        : "K12",
        "HA23_N"        : "J11",
        "HA23_P"        : "K11",

        "GBTCLK0_M2C_N" : "AK39",
        "GBTCLK0_M2C_P" : "AK38",
        "GBTCLK1_M2C_N" : "AH39",
        "GBTCLK1_M2C_P" : "AH38",
        "GBTCLK2_M2C_N" : "AF39",
        "GBTCLK2_M2C_P" : "AF38",
        "GBTCLK3_M2C_N" : "AB39",
        "GBTCLK3_M2C_P" : "AB38",
        "GBTCLK4_M2C_N" : "R41",
        "GBTCLK4_M2C_P" : "R40",
        "GBTCLK5_M2C_N" : "AN41",
        "GBTCLK5_M2C_P" : "AN40",

        "REFCLK_C2M_N"  : "AP33",
        "REFCLK_C2M_P"  : "AN33",
        "REFCLK_M2C_N"  : "AL34",
        "REFCLK_M2C_P"  : "AK34",

        "SYNC_C2M_N"    : "AN35",
        "SYNC_C2M_P"    : "AN34",
        "SYNC_M2C_N"    : "AN36",
        "SYNC_M2C_P"    : "AM36",

        "DP0_C2M_N"     : "AT43",
        "DP0_C2M_P"     : "AT42",
        "DP0_M2C_N"     : "AR46",
        "DP0_M2C_P"     : "AR45",
        "DP1_C2M_N"     : "AP43",
        "DP1_C2M_P"     : "AP42",
        "DP1_M2C_N"     : "AN46",
        "DP1_M2C_P"     : "AN45",
        "DP2_C2M_N"     : "AM43",
        "DP2_C2M_P"     : "AM42",
        "DP2_M2C_N"     : "AL46",
        "DP2_M2C_P"     : "AL45",
        "DP3_C2M_N"     : "AL41",
        "DP3_C2M_P"     : "AL40",
        "DP3_M2C_N"     : "AJ46",
        "DP3_M2C_P"     : "AJ45",
        "DP4_C2M_N"     : "T43",
        "DP4_C2M_P"     : "T42",
        "DP4_M2C_N"     : "W46",
        "DP4_M2C_P"     : "W45",
        "DP5_C2M_N"     : "P43",
        "DP5_C2M_P"     : "P42",
        "DP5_M2C_N"     : "U46",
        "DP5_M2C_P"     : "U45",
        "DP6_C2M_N"     : "M43",
        "DP6_C2M_P"     : "M42",
        "DP6_M2C_N"     : "R46",
        "DP6_M2C_P"     : "R45",
        "DP7_C2M_N"     : "K43",
        "DP7_C2M_P"     : "K42",
        "DP7_M2C_N"     : "N46",
        "DP7_M2C_P"     : "N45",
        "DP8_C2M_N"     : "AK43",
        "DP8_C2M_P"     : "AK42",
        "DP8_M2C_N"     : "AG46",
        "DP8_M2C_P"     : "AG45",
        "DP9_C2M_N"     : "AJ41",
        "DP9_C2M_P"     : "AJ40",
        "DP9_M2C_N"     : "AF44",
        "DP9_M2C_P"     : "AF43",
        "DP10_C2M_N"    : "AG41",
        "DP10_C2M_P"    : "AG40",
        "DP10_M2C_N"    : "AE46",
        "DP10_M2C_P"    : "AE45",
        "DP11_C2M_N"    : "AE41",
        "DP11_C2M_P"    : "AE40",
        "DP11_M2C_N"    : "AD44",
        "DP11_M2C_P"    : "AD43",
        "DP12_C2M_N"    : "AC41",
        "DP12_C2M_P"    : "AC40",
        "DP12_M2C_N"    : "AC46",
        "DP12_M2C_P"    : "AC45",
        "DP13_C2M_N"    : "AA41",
        "DP13_C2M_P"    : "AA40",
        "DP13_M2C_N"    : "AB44",
        "DP13_M2C_P"    : "AB43",
        "DP14_C2M_N"    : "W41",
        "DP14_C2M_P"    : "W40",
        "DP14_M2C_N"    : "AA46",
        "DP14_M2C_P"    : "AA45",
        "DP15_C2M_N"    : "U41",
        "DP15_C2M_P"    : "U40",
        "DP15_M2C_N"    : "Y44",
        "DP15_M2C_P"    : "Y43",
        "DP16_C2M_N"    : "H43",
        "DP16_C2M_P"    : "H42",
        "DP16_M2C_N"    : "L46",
        "DP16_M2C_P"    : "L45",
        "DP17_C2M_N"    : "F43",
        "DP17_C2M_P"    : "F42",
        "DP17_M2C_N"    : "J46",
        "DP17_M2C_P"    : "J45",
        "DP18_C2M_N"    : "D43",
        "DP18_C2M_P"    : "D42",
        "DP18_M2C_N"    : "G46",
        "DP18_M2C_P"    : "G45",
        "DP19_C2M_N"    : "B43",
        "DP19_C2M_P"    : "B42",
        "DP19_M2C_N"    : "E46",
        "DP19_M2C_P"    : "E45",
        "DP20_C2M_N"    : "BD43",
        "DP20_C2M_P"    : "BD42",
        "DP20_M2C_N"    : "BC46",
        "DP20_M2C_P"    : "BC45",
        "DP21_C2M_N"    : "BB43",
        "DP21_C2M_P"    : "BB42",
        "DP21_M2C_N"    : "BA46",
        "DP21_M2C_P"    : "BA45",
        "DP22_C2M_N"    : "AY43",
        "DP22_C2M_P"    : "AY42",
        "DP22_M2C_N"    : "AW46",
        "DP22_M2C_P"    : "AW45",
        "DP23_C2M_N"    : "AV43",
        "DP23_C2M_P"    : "AV42",
        "DP23_M2C_N"    : "AU46",
        "DP23_M2C_P"    : "AU45",

        "H_PRSNT_M2C_B" : "AM33",
        "Z_PRSNT_M2C_B" : "AM29",
    }),
]

# Platform -----------------------------------------------------------------------------------------

class Platform(XilinxUSPPlatform):
    default_clk_name   = "clk125"
    default_clk_period = 1e9/125e6

    def __init__(self, toolchain="vivado"):
        XilinxUSPPlatform.__init__(self, "xcvu9p-flga2104-2-e", _io, _connectors, toolchain="vivado")

    def create_programmer(self):
        return VivadoProgrammer()

    def do_finalize(self, fragment):
        XilinxUSPPlatform.do_finalize(self, fragment)
        self.add_period_constraint(self.lookup_request("clk300",    loose=True), 1e9/300e6)
        self.add_period_constraint(self.lookup_request("clk250", 0, loose=True), 1e9/250e6)
        self.add_period_constraint(self.lookup_request("clk250", 1, loose=True), 1e9/250e6)
        self.add_period_constraint(self.lookup_request("clk125",    loose=True), 1e9/125e6)
        self.add_period_constraint(self.lookup_request("clk156",    loose=True), 1e9/156e6)
        # DDR4 memory channel C1 Internal Vref
        self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 71]")
        self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 72]")
        self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 73]")
        # DDR4 memory channel C2 Internal Vref
        self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 40]")
        self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 41]")
        self.add_platform_command("set_property INTERNAL_VREF 0.84 [get_iobanks 42]")
